package com.strongbj.iot.devices.newlight.response.handle;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.strongbj.core.message.IMessageHandle;
import com.strongbj.core.util.ByteUtil;
import com.strongbj.core.util.ContextUtils;
import com.strongbj.iot.devices.newlight.Constans;
import com.strongbj.iot.devices.newlight.common.Executer;
import com.strongbj.iot.devices.newlight.common.NetMapping;
import com.strongbj.iot.devices.newlight.entity.T;
import com.strongbj.iot.devices.newlight.entity.Tag;
import com.strongbj.iot.devices.newlight.entity.TagReg;
import com.strongbj.iot.devices.newlight.message.NewLightOSMessageFactory;
import com.strongbj.iot.devices.newlight.message.NewLightReaderMessage;
import com.strongbj.iot.devices.newlight.response.common.HandleTimeStamp;
import com.strongbj.iot.devices.newlight.service.TagRegService;
import com.strongbj.iot.devices.newlight.service.TagService;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;

/**
 * 类型码：0x01，标签信号测试或自动请求入网
 * 老方法，由TagAccessRequestHandle类代替
 * @author lei_w
 *
 */
public class LableSignalTestResponseHandle implements IMessageHandle<NewLightReaderMessage, Object> {

	private static Logger logger = LogManager.getLogger(LableSignalTestResponseHandle.class.getName());

	private TagRegService tagRegService = (TagRegService) ContextUtils.getBean("tagRegService");

	private TagService tagService = (TagService) ContextUtils.getBean("tagService");

	private NewLightOSMessageFactory newLightOSMessageFactory = (NewLightOSMessageFactory) ContextUtils
			.getBean("newLightOSMessageFactory");

	@Override
	public boolean isHandle(NewLightReaderMessage t) {
		if (Integer.valueOf("1", 16).byteValue() == t.getType()) {
			return true;
		} else {
			return false;
		}
	}

	@Override
	public Object handle(ChannelHandlerContext ctx, NewLightReaderMessage t) {

		String hostNumber = ByteUtil.bytesToAddress(t.getAddress()); // reader 地址码
		String timeStamp = ByteUtil.byteArrToHexString(t.getTime()); // 时间戳
		// 返回正文：4 字节 LED 标签地址 + 1 字节接收成功的测试包数量 + 保留字段。
		// String ledTag = ByteUtil.byteArrToHexString(t.getBody(), 0, 4); // LED 标签地址
		String ledTag = ByteUtil.bytesToIp(ByteUtil.subBytes(t.getBody(), 0, 4));// LED 标签地址
		int testPack = ByteUtil.hexStringToInt(ByteUtil.byteArrToHexString(t.getBody(), 4, 1)); // 1 字节接收成功的测试包数量
		String log = "\r\n===================================================" + "\r\n收到标签信号测试或自动请求入网报文："
				+ "\r\n READER地址码：" + hostNumber + "\r\n LED标签地址： " + ledTag + "\r\n 测试包数量：" + testPack + "\r\n 时间戳："
				+ HandleTimeStamp.handle(timeStamp) + "\r\n===================================================";
		logger.info(log);

		// 收到标签信号测试或自动请求入网报文启动定时器
		// 判断是否第一次收到入网报文
		synchronized (Constans.isFirst) {
			if (Constans.isFirst) {
				Constans.isFirst = false;
				// 清空标签质量存储集合
				Constans.bestList.clear();
				Constans.secList.clear();
				// 启动定时任务，1秒后统计标签质量进行绑签
				Timer timer = new Timer();
				timer.schedule(new TimerTask() {
					@Override
					public void run() {
						try {
							logger.info("=============2S执行绑定=============");
							// 执行标签绑定
							// 待绑定标签
							List<Tag> tags = tagRegService.bingTagReg(Constans.bestList, Constans.secList);
//							if (tags == null || tags.size() == 0)
//								return;
							logger.info("=============获取待绑定标签数据" + tags.size() + "=============");
							// 插入数据库
							logger.info("=============插入标签数据库=============");
							tagService.saveOrUpdateBatch(tags);
							// 循环发送标签绑定命令
							for (Tag t : tags) {
								logger.info("=============循环发送绑定命令=============");
								byte[] sendData = new byte[6];
								byte[] data = ByteUtil.ipToBytesByInet(t.getIp());
								System.arraycopy(data, 0, sendData, 0, 4);
								sendData[4] = 0x3e;
								sendData[5] = 0x00;
								byte[] req = newLightOSMessageFactory.createNewLightOSMessage(
										ByteUtil.addressToBytes(t.getReader()), (byte) 0x02, sendData,
										T.getTimeStamp());
								ByteBuf bs = Unpooled.copiedBuffer(req);
								
								//使用队列发送命令
								Map<String,Object> args = new HashMap<String,Object>();
								args.put("code", t.getReader());
								args.put("tag", t.getIp());
								args.put("req", req);
								Executer.RunCmd("BindTag", t.getReader(), bs, args, T.getTimeStamp());
								
								//NetMapping.getInstance().getChannels().writeAndFlush(bs);
							}
						} catch (Exception ex) {
							ex.printStackTrace();
						}
						Constans.isFirst = true;
					}
				}, 1000);
			}
			// 对比待绑定集合中信号强度
			if (Integer.valueOf(testPack) > 5) {
				if (Constans.bestList.get(ledTag) == null) {
					TagReg tagReg = new TagReg();
					tagReg.setId(IdWorker.getId());
					tagReg.setReader(hostNumber);
					tagReg.setTagIp(ledTag);
					tagReg.setQuality(Integer.valueOf(testPack));
					Constans.bestList.put(ledTag, tagReg);
					return null;
				} else if (Constans.bestList.get(ledTag).getQuality() < Integer.valueOf(testPack)) {
					TagReg tagReg = new TagReg();
					tagReg.setId(IdWorker.getId());
					tagReg.setReader(hostNumber);
					tagReg.setTagIp(ledTag);
					tagReg.setQuality(Integer.valueOf(testPack));
					Constans.bestList.put(ledTag, tagReg);
					return null;
				} else if (Constans.secList.get(ledTag) == null
						&& Constans.bestList.get(ledTag).getReader() != hostNumber) {
					TagReg tagReg = new TagReg();
					tagReg.setId(IdWorker.getId());
					tagReg.setReader(hostNumber);
					tagReg.setTagIp(ledTag);
					tagReg.setQuality(Integer.valueOf(testPack));
					Constans.secList.put(ledTag, tagReg);
					return null;
				} else if (Constans.secList.get(ledTag) != null
						&& Constans.bestList.get(ledTag).getReader() != hostNumber
						&& Constans.secList.get(ledTag).getQuality() < Integer.valueOf(testPack)) {
					TagReg tagReg = new TagReg();
					tagReg.setId(IdWorker.getId());
					tagReg.setReader(hostNumber);
					tagReg.setTagIp(ledTag);
					tagReg.setQuality(Integer.valueOf(testPack));
					Constans.secList.put(ledTag, tagReg);
					return null;
				}
			}
		}
		return null;
	}

	@Override
	public void destory() {
		// TODO Auto-generated method stub
		
	}

}
